<script setup lang="ts">
defineOptions({
  name: "importFiles"
});
import { ref } from "vue";
import { PxMessage, PxMessageBox } from "px-ui";
import { Loading } from "@px-ui/icons-vue";
import { loadingTimeout } from "@/utils/http/constant";
import default_ from "@/assets/svg/file/default.svg?component";
import error_ from "@/assets/svg/file/error.svg?component";

interface Props {
  isNotImmediateUpload?: boolean;
  params?: Record<string, any> | null;
  uploadApi?: (p?: any) => Promise<any>;
  drag?: boolean;
  accept?: string;
  showFileList?: boolean;
  dialogSuccess?: boolean;
  limit?: number;
  size?: number;
  prop?: Record<string, any> | null;
  upfileid: string;
}

const props = withDefaults(defineProps<Props>(), {
  isNotImmediateUpload: false,
  params: null,
  drag: true,
  accept: ".xlsx, .xls",
  showFileList: false,
  limit: 1,
  size: 100,
  prop: null,
  upfileid: ""
});

const result = defineModel({ type: Object, default: null });
const uploadRef = ref<any>(null);
const loading = ref<boolean>(false);
const success = ref<boolean>(false);
const successText = ref<string>("");
const error = ref<boolean>(false);
const errorText = ref<string>("");
const isError = ref<boolean>(false);
const successClose = () => {
  success.value = false;
  successText.value = "";
};
const emits = defineEmits(["submit"]);
defineExpose({
  successClose
});
/**
 * @description: 上传前校验
 * @param {*} file
 * @return {*}
 */
const beforeUPload = (file: any) => {
  loading.value = true;
  setTimeout(() => {
    loading.value = false;
  }, loadingTimeout);
  const isExcel = file.type === "application/vnd.ms-excel" || file.type === "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
  const isLt2M = file.size / 1024 / 1024 < props.size;
  if (!isExcel)
    PxMessageBox({
      title: "温馨提示",
      message: `上传文件格式只支持 ${props.accept} 格式！`,
      type: "warning"
    });
  if (!isLt2M)
    PxMessageBox({
      title: "温馨提示",
      message: `上传文件大小不能超过 ${props.size} MB!`,
      type: "warning"
    });
  return isExcel && isLt2M;
};

/**
 * @description:  文件数超出提示
 * @return {*}
 */
const exceedFile = () => {
  PxMessage.warning(`最多只能上传 ${props.limit} 个文件！`);
};

/**
 * @description:  上传错误提示
 * @return {*}
 */
const handleError = () => {
  isError.value = true;
  PxMessage.error("导入失败，请重新上传！");
  errorText.value = "导入失败，请查看导入内容是否正确，重新上传！";
  successText.value = "";
  loading.value = false;
  error.value = true;
  success.value = false;
  uploadRef.value.clearFiles();
};

/**
 * @description:  文件上传
 * @param {*} params
 * @return {*}
 */
const uploadExcel = async (params: any) => {
  isError.value = false;
  result.value = params;
  if (props.isNotImmediateUpload) {
    emits("submit", result.value);
    successText.value = "";
    errorText.value = "";
    loading.value = false;
    success.value = true;
    error.value = false;
    uploadRef.value.clearFiles();
    return;
  }
  let fileFormData = new FormData();
  if (props.params) {
    for (const key in props.params) {
      fileFormData.append(key, props.params[key]);
    }
  }
  fileFormData.append("file", params.file);
  fileFormData.append("classCode", props.upfileid);
  const res = await props.uploadApi(fileFormData);
  console.log(res);
  if (!res) {
    successText.value = `导入成功！`;
  } else {
    successText.value = `导入成功`;
  }
  errorText.value = "";
  loading.value = false;
  success.value = true;
  error.value = false;
  emits("submit", res);
  uploadRef.value.clearFiles();
};
</script>

<template>
  <px-upload
    ref="uploadRef"
    class="upload-demo"
    action=""
    :drag="drag"
    :accept="accept"
    :show-file-list="showFileList"
    :limit="limit"
    :on-exceed="exceedFile"
    :on-error="handleError"
    :http-request="uploadExcel"
    :before-upload="beforeUPload"
    v-bind="prop"
  >
    <px-icon class="px-icon--upload">
      <error_ v-if="isError" />
      <default_ v-else />
    </px-icon>
    <div v-if="success" class="file-name">{{ result.file.name }}</div>
    <div v-else class="px-upload__text">
      拖拽到这里或
      <span class="px-upload__color">点击上传</span>
    </div>
    <div v-if="success && successText" class="success-text">{{ successText }}</div>
    <div v-if="error && errorText" class="error-text">{{ errorText }}</div>
    <div v-if="loading" class="loading">
      <px-icon class="is-loading">
        <Loading />
      </px-icon>
      <span class="text">正在导入</span>
    </div>
    <div v-if="success || error" class="btns error">
      <px-button type="primary" :plain="success">{{ success ? "再次导入" : error ? "重新导入" : "" }}</px-button>
    </div>
  </px-upload>
</template>

<style lang="scss" scoped>
.upload-demo {
  .px-icon--upload {
    font-size: 50px;
  }

  .px-upload__text {
    .px-upload__color {
      color: #3b82f6;
    }
  }

  .file-name {
    color: #333;
  }

  .success-text {
    color: #666;
  }

  .error-text {
    color: #666;
  }

  .loading {
    display: flex;
    gap: 4px;
    align-items: center;
    justify-content: center;
    margin-top: 12px;

    .px-icon {
      font-size: 18px;
    }

    .text {
      font-size: 12px;
      color: #999;
    }
  }

  .btns {
    display: flex;
    align-items: center;
    justify-content: center;
    margin-top: 12px;
  }
}
</style>
